package com.html.common;

import com.html.blog.controller.BlogController;
import com.html.blog.model.Blog;
import com.html.index.IndexController;
import com.jfinal.config.*;
import com.jfinal.core.JFinal;
import com.jfinal.kit.PropKit;
import com.jfinal.plugin.activerecord.ActiveRecordPlugin;
import com.jfinal.plugin.c3p0.C3p0Plugin;

/**
 * API引导式配置
 */
public class DemoConfig extends JFinalConfig {
	
	/**
	 * 配置常量：如开发模式常量 devMode 的配置,默认视图类型 ViewType 的配置
	 */
	public void configConstant(Constants me) {
		// 加载少量必要配置，随后可用getProperty(...)获取值
		PropKit.use("a_little_config.txt");
		// 在开发模式下,JFinal 会对每次请求输出报告,如输出本次请求的 Controller、Method 以
		// 及请求所携带的参数。JFinal 支持 JSP、FreeMarker、Velocity 三种常用视图。
		me.setDevMode(PropKit.getBoolean("devMode", false));
	}
	
	/**
	 * 配置路由
	 */
	public void configRoute(Routes me) {
		me.add("/", IndexController.class, "/index");	// 第三个参数为该Controller的视图存放路径，当 viewPath 未指定时默认值为 controllerKey。
		me.add("/blog", BlogController.class);			// 第三个参数省略时默认与第一个参数值相同，在此即为 "/blog"
		// http://localhost/blog 将 访 问 BlogController.index() 方 法 , 而
		// http://localhost/blog/methodName 将访问到 BlogController.methodName()方法。当 methodName 省略时默认值为 index。

		// controllerKey/method/v0-v1
		// urlPara 可以在一次请求中同时携带多个值,JFinal 默认使用减号“-”来分隔多个值(可
		// 通过 constants.setUrlParaSeparator(String)设置分隔符),在 Controller 中可以通过 getPara(int
		// index)分别取出这些值。controllerKey、method、urlPara 这三部分必须使用正斜杠“/”分隔。

		// 注意,controllerKey 自身也可以包含正斜杠“/”,如“/admin/article”,这样实质上实现了
		// struts2 的 namespace 功能。
	}
	
	/**
	 * 配置插件
	 */
	public void configPlugin(Plugins me) {
		// 配置C3p0数据库连接池插件
		C3p0Plugin c3p0Plugin = new C3p0Plugin(PropKit.get("jdbcUrl").trim(), PropKit.get("user").trim(), PropKit.get("password").trim());
		me.add(c3p0Plugin);
		
		// 配置ActiveRecord插件
		ActiveRecordPlugin arp = new ActiveRecordPlugin(c3p0Plugin);
		me.add(arp);
		arp.addMapping("blog", Blog.class);	// 映射blog表 到 Blog模型
	}
	
	/**
	 * 配置全局拦截器
	 */
	public void configInterceptor(Interceptors me) {
		
	}
	
	/**
	 * 配置处理器
	 */
	public void configHandler(Handlers me) {
		
	}
	
	/**
	 * 建议使用 JFinal 手册推荐的方式启动项目
	 * 运行此 main 方法可以启动项目，此main方法可以放置在任意的Class类定义中，不一定要放于此
	 */
	public static void main(String[] args) {
		JFinal.start("/home/taomk/king-jfinal/jfinal-demo/src/main/webapp", 8080, "/", 5);
	}

	/**
	 * Dialect  多数据库支持 默认是MysqlDialect：
	 * 目前 ActiveRecordPlugin 提供了 MysqlDialect、OracleDialect、AnsiSqlDialect 实现类。
	 * MysqlDialect 与 OracleDialect 分别实现对 Mysql 与 Oracle 的支持，AnsiSqlDialect 实现对遵守
	 * ANSI SQL 数据库的支持。以下是数据库 Dialect 的配置代码：
	 * public class DemoConfig extends JFinalConfig {
	 * 		public void configPlugin(Plugins me) {
	 * 			ActiveRecordPlugin arp = new ActiveRecordPlugin(…);
	 * 			me.add(arp);
	 * 			// 配置Postgresql方言
	 * 			arp.setDialect(new PostgresqlDialect());
	 * 		}
	 * }
	 *
	 * Oracle 数据库具有一定的特殊性，JFinal 针对这些特殊性进行了一些额外的支持以方便广
	 * 大的 Oracle 使用者。以下是一个完整的 Oracle 配置示例：
	 * public class DemoConfig extends JFinalConfig {
	 * 		public void configPlugin(Plugins me) {
	 * 			C3p0Plugin cp = new C3p0Plugin(……);
	 * 			//配置Oracle驱动
	 * 			cp. setDriverClass("oracle.jdbc.driver.OracleDriver");
	 * 			me.add(cp);
	 * 			ActiveRecordPlugin arp = new ActiveRecordPlugin(cp);
	 * 			me.add(arp);
	 * 			// 配置Oracle方言
	 * 			arp.setDialect(new OracleDialect());
	 * 			// 配置属性名(字段名)大小写不敏感容器工厂
	 * 			arp.setContainerFactory(new CaseInsensitiveContainerFactory());
	 * 			arp.addMapping("user", "user_id", User.class);
	 * 		}
	 * }
	 *
	 * 由于Oracle数据库会自动将属性名(字段名)转换成大写，所以需要手动指定主键名为大写，
	 * 如：arp.addMaping(“user”, “ID”, User.class)。如果想让 ActiveRecord 对属性名（字段名）的大
	 * 小写不敏感可以通过设置 CaseInsensitiveContainerFactory 来达到，有了这个设置，则
	 * arp.addMaping(“user”, “ID”, User.class)不再需要了。

	 * 另外，Oracle 并未直接支持自增主键，JFinal 为此提供了便捷的解决方案。要让 Oracle 支
	 * 持自动主键主要分为两步：一是创建序列，二是在 model 中使用这个序列，具体办法如下：
	 * 1：通过如下办法创建序列，本例中序列名为：MY_SEQ
	 * CREATE SEQUENCE MY_SEQ
	 * 	INCREMENT BY 1
	 * 	MINVALUE 1
	 *  MAXVALUE 9999999999999999
	 * 	START WITH 1
	 * 	CACHE 20;
	 *
	 * 2：在 YourModel.set(…)中使用上面创建的序列
	 * // 创建User并使用序列
	 * User user = new User().set("id", "my_seq.nextval").set("age", 18);
	 * user.save();
	 * // 获取id值
	 * Integer id = user.get("id");
	 *
	 * 多数据源支持：
	 * ActiveRecordPlugin 可同时支持多数据源、多方言、多缓存、多事务级别等特性，对每个
	 * ActiveRecordPlugin 可进行彼此独立的配置。简言之 JFinal 可以同时使用多数据源，并且可
	 * 以针对这多个数据源配置独立的方言、缓存、事务级别等。
	 * 当使用多数据源时，只需要对每个 ActiveRecordPlugin 指定一个 configName 即可，如下是
	 * 代码示例：
	 * public void configPlugin(Plugins me) {
	 * 		// mysql 数据源
	 * 		C3p0Plugin dsMysql = new C3p0Plugin(…);
	 * 		me.add(dsMysql);
	 * 		// mysql ActiveRecordPlugin 实例，并指定configName为 mysql
	 * 		ActiveRecordPlugin arpMysql = new ActiveRecordPlugin("mysql", dsMysql);
	 * 		me.add(arpMysql);
	 * 		arpMysql.setCache(new EhCache());
	 * 		arpMysql.addMapping("user", User.class);
	 * 		// oracle 数据源
	 * 		C3p0Plugin dsOracle = new C3p0Plugin(…);
	 * 		me.add(dsOracle);
	 * 		// oracle ActiveRecordPlugin 实例，并指定configName为 oracle
	 * 		ActiveRecordPlugin arpOracle = new ActiveRecordPlugin("oracle", dsOracle);
	 * 		me.add(arpOracle);
	 * 		arpOracle.setDialect(new OracleDialect());
	 * 		arpOracle.setTransactionLevel(8);
	 * 		arpOracle.addMapping("blog", Blog.class);
	 * }
	 *
	 * 以上代码创建了创了两个 ActiveRecordPlugin 实例 arpMysql 与 arpOracle，特别注意创建实
	 * 例的同时指定其 configName 分别为 mysql 与 oracle。arpMysql 与 arpOracle 分别映射了不同的
	 * Model，配置了不同的方言。
	 *
	 * 对于 Model 的使用，不同的 Model 会自动找到其所属的 ActiveRecordPlugin 实例以及相关
	 * 配置进行数据库操作。对于 Db + Record 的使用，需要使用 Db.use(configName)方法得到数据库
	 * 操作对象，然后就可以进行数据库操作了，以下是代码示例：
	 *
	 * // 查询 dsMysql数据源中的 user
	 * List<Record> users = Db.use("mysql").find("select * from user");
	 * // 查询 dsOracle数据源中的 blog
	 * List<Record> blogs = Db.use("oracle").find("select * from blog");
	 *
	 * 以上两行代码，分别通过 configName 为 mysql、oracle 得到各自的数据库操作对象，然后
	 * 就可以如同单数据完全一样的方式来使用数据库操作 API 了。简言之，对于 Db + Record 来
	 * 说，多数据源相比单数据源仅需多调用一下 Db.use(configName)，随后的 API 使用方式完全一
	 * 样。
	 * 注意最先创建的 ActiveRecrodPlugin 实例将会成为主数据源，可以省略 configName。最先
	 * 创建的 ActiveRecrodPlugin 实例中的配置将默认成为主配置，此外还可以通过设置 configName
	 * 为 DbKit.MAIN_CONFIG_NAME 常量来设置主配置。
	 */
}
